<!DOCTYPE html>
<html lang="zh">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimal-ui">
<meta name="keywords" content="LightYear,LightYearAdmin,光年,后台模板,后台管理系统,光年HTML模板">
<meta name="description" content="Light Year Admin V5是一个基于Bootstrap v5.1.3的后台管理系统的HTML模板。">
<meta name="author" content="yinq">
<title>首页 - 光年(Light Year Admin V5)后台管理系统模板</title>
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-touch-fullscreen" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="default">
<link rel="stylesheet" type="text/css" href="css/materialdesignicons.min.css">
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="css/animate.min.css">
<!--弹窗插件css-->
<link rel="stylesheet" type="text/css" href="js/jquery-confirm/jquery-confirm.min.css">
<!--表格插件css-->
<link rel="stylesheet" href="js/bootstrap-table/bootstrap-table.min.css">
<link rel="stylesheet" type="text/css" href="css/style.min.css">
</head>

<body>
<div class="container-fluid">

  <div class="row">

  	<div class="col-lg-12">
  	  <div class="card">
  	    <header class="card-header">
  	      <div class="card-title">新闻列表</div>
  	    </header>
  		<div class="card-body">
          
  		  <p>关于modal的增加和修改，其实我在js_fullcalendar，日程插件示例里面已有用到。这里引入bootstrap-table来制作列表，用以演示一个完整的增删改查流程。</p>
          <div class="callout callout-danger mb-3">
            <p>这里因为是用mock模拟的接口，数据都是数组，所以排序这个就没有做到返回正常的结果。</p>
            <p>另外一个就是，修改数据的mock接口里面做的是删除和插入新的，所以返回的结果上数据顺序会不一样，不用疑问哈。</p>
          </div>
          <div class="row search-box">
            <div class="col-md-4">
              <div class="row">
                <label class="col-sm-3 col-form-label">标题</label>
                <div class="col-sm-9">
                  <input type="text" class="form-control" name="title" id="title" value="" placeholder="请输入标题">
                </div>
              </div>
            </div>
            <div class="col-md-2">
              <button type="submit" class="btn btn-primary me-1" id="search-btn">搜索</button>
            </div>
          </div>
          <div id="toolbar" class="toolbar-btn-action">
            <button id="add-btn" type="button" class="btn btn-primary me-1">
              <span class="mdi mdi-plus" aria-hidden="true"></span> 新增
            </button>
            <button type="button" class="edit-btn btn btn-success me-1" data-status="1">
              <span class="mdi mdi-check" aria-hidden="true"></span> 启用
            </button>
            <button type="button" class="edit-btn btn btn-warning me-1" data-status="0">
              <span class="mdi mdi-block-helper" aria-hidden="true"></span> 禁用
            </button>
            <button id="del-btn" type="button" class="btn btn-danger">
              <span class="mdi mdi-window-close" aria-hidden="true"></span> 删除
            </button>
          </div>
  	      <table id="table"></table>
          
  	    </div>
  	  </div>
    </div>

  </div>

</div>
<!--Start 模态框-->
<div class="modal fade" id="newsModal">
  <div class="modal-dialog modal-xl">
    <div class="modal-content">
      <form action="/news/save" method="post" class="save-form" novalidate>
      <div class="modal-header">
        <h6 class="modal-title"><span>新增</span>新闻</h6>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        <div class="row">
          <div class="mb-3 col-md-12">
            <label for="type" class="form-label">栏目</label>
            <div class="form-controls">
              <select name="type" class="form-select" id="type" required>
                <option value="1">小说</option>
                <option value="2">古籍</option>
                <option value="3">专辑</option>
                <option value="4">自传</option>
              </select>
              <div class="invalid-feedback">请选择栏目</div>
            </div>
          </div>
          <div class="mb-3 col-md-12">
            <label for="title" class="form-label">标题</label>
            <input type="text" class="form-control" id="title" name="title" value="" placeholder="请输入标题" required />
            <div class="invalid-feedback">请填写新闻标题</div>
          </div>
          <div class="mb-3 col-md-12">
            <label for="seo_keywords" class="form-label">作者</label>
            <input type="text" class="form-control" id="author" name="author" value="" placeholder="作者" required />
            <div class="invalid-feedback">请填写新闻作者</div>
          </div>
          <div class="mb-3 col-md-12">
            <label for="content" class="form-label">内容（这里不做富文本了）</label>
            <textarea class="form-control" id="content" name="content" rows="5" value="" placeholder="内容" required></textarea>
            <div class="invalid-feedback">请填写新闻内容</div>
          </div>
          <div class="mb-3 col-md-12">
            <label for="sort" class="form-label">排序</label>
            <input type="text" class="form-control" id="sort" name="sort" value="0" />
          </div>
          <div class="mb-3 col-md-12">
            <label for="status" class="form-label">状态</label>
            <div class="clearfix">
              <div class="form-check form-check-inline">
      	        <input type="radio" id="statusOne" name="status" class="form-check-input" value="0">
      	        <label class="form-check-label" for="statusOne">禁用</label>
      	      </div>
      	      <div class="form-check form-check-inline">
      	        <input type="radio" id="statusTwo" name="status" class="form-check-input" value="1" checked>
      	        <label class="form-check-label" for="statusTwo">启用</label>
      	      </div>
            </div>
          </div>
        </div>
      </div>
      <div class="modal-footer">
        <input type="hidden" name="id" id="news_id" value="" />
        <button type="button" class="btn btn-secondary close-btn">关闭</button>
        <button type="submit" class="btn btn-primary save-btn">保存</button>
      </div>
      </form>
    </div>
  </div>
</div>
<!--End 模态框-->
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/popper.min.js"></script>
<script type="text/javascript" src="js/bootstrap.min.js"></script>
<script type="text/javascript" src="js/lyear-loading.js"></script>
<script type="text/javascript" src="js/bootstrap-notify.min.js"></script>
<script type="text/javascript" src="js/jquery-confirm/jquery-confirm.min.js"></script>
<script type="text/javascript" src="js/main.min.js"></script>
<!--表格插件js-->
<script src="js/bootstrap-table/bootstrap-table.js"></script>
<script src="js/bootstrap-table/locale/bootstrap-table-zh-CN.min.js"></script>

<!--mock是模拟接口用的，实际使用中不用引入这些-->
<script type="text/javascript" src="data/mock.min.js"></script>
<script type="text/javascript" src="data/news.js"></script>
<script type="text/javascript">
    var newsModal; // 模态框
    
    /**
     * 绑定模态框隐藏事件
     */
    $('#newsModal').get(0).addEventListener('hidden.bs.modal', function (event) {
        $('.save-form').removeClass('was-validated');
        $('.save-form').get(0).reset();
        $('#news_id').val("");
    })
    
    /**
     * 新增按钮
     */
    $(document).on('click', '#add-btn', function () {
        $('#newsModal').find('.modal-title span').text('添加');
        newsModal = new bootstrap.Modal($('#newsModal').get(0), {
            keyboard: false,
            backdrop: 'static',
        });
        newsModal.show();
    });
    
    /**
     * 批量 删除按钮
     */
    $(document).on('click', '#del-btn', function () {
        var self    = $(this);
        var selRows = $('#table').bootstrapTable("getSelections");
        if(selRows.length == 0){
            showNotify("请至少选择一行", 'danger');
            return;
        }
        var postData = "";
        $.each(selRows,function(i) {
            postData +=  this.id;
            if (i < selRows.length - 1) {
                postData += ",";
            }
        });
      
        $.confirm({
            title: '',
            content: '确认要执行该操作吗？',
            type: 'orange',
            typeAnimated: true,
            buttons: {
                confirm: {
                    text: '确认',
                    btnClass: 'btn-blue',
                    action: function() {
                        var loader = $('body').lyearloading({
                            opacity: 0.2,
                            spinnerSize: 'lg'
                        });
                        self.attr('autocomplete', 'off').prop('disabled', true);
                        jQuery.post('/news/delete', { ids: postData }).done(function(res) {
                            loader.destroy();
                            var res = eval('(' + res + ')');
                            var msg = res.msg;
                            if (200 == res.code) {
                                showNotify(msg, 'info');
                                $("#table").bootstrapTable('refresh');
                            } else {
                                showNotify(msg, 'danger');
                            }
                            self.attr("autocomplete", "on").prop("disabled", false);
                        }).fail(function () {
                            loader.destroy();
                            showNotify('服务器发生错误，请稍后再试', 'danger');
                            self.attr("autocomplete", "on").prop("disabled", false);
                        });
                    }
                },
                cancel: {
                    text: '取消',
                    action: function() {}
                }
            }
        });
        return false;
    });
    
    /**
     * 批量 开启/禁用按钮
     */
    $(document).on('click', '.edit-btn', function () {
        var self    = $(this);
        var selRows = $('#table').bootstrapTable("getSelections");
        if(selRows.length == 0){
            showNotify("请至少选择一行", 'danger');
            return;
        }
        var postData = "";
        $.each(selRows,function(i) {
            postData +=  this.id;
            if (i < selRows.length - 1) {
                postData += ",";
            }
        });
        
        var loader = $('body').lyearloading({
            opacity: 0.2,
            spinnerSize: 'lg'
        });
        jQuery.post('/news/setStatus', { ids: postData, status: self.data('status') }).done(function(res) {
            loader.destroy();
            var res = eval('(' + res + ')');
            var msg = res.msg;
            if (200 == res.code) {
                showNotify(msg, 'info');
                $("#table").bootstrapTable('refresh');
            } else {
                showNotify(msg, 'danger');
            }
            self.attr("autocomplete", "on").prop("disabled", false);
        }).fail(function () {
            loader.destroy();
            showNotify('服务器发生错误，请稍后再试', 'danger');
            self.attr("autocomplete", "on").prop("disabled", false);
        });
    });
    
    /**
     * 关闭按钮
     */
    $(document).on('click', '.close-btn', function () {
        newsModal.hide();
    });
    
    /**
     * 保存按钮
     */
    $(document).on('click', '.save-btn', function (event) {
        var form      = $('.save-form');
        var form_data = form.serialize();
        var ajax_url  = form.attr('action');
        var self      = $(this);
        
        // 这里只做不为空的验证
        form.get(0).classList.add('was-validated');
        if (!form.get(0).checkValidity()) {
            event.preventDefault();
            event.stopPropagation();
            return false;
        }
      
        self.attr('autocomplete', 'off').prop('disabled', true);
        
        var loader = $('body').lyearloading({
            opacity: 0.2,
            spinnerSize: 'lg'
        });
        
        jQuery.post(ajax_url, form_data).done(function(res) {
            loader.destroy();
            var res = eval('(' + res + ')');
            var msg = res.msg;
            if (200 == res.code) {
                showNotify(msg, 'info');
                $("#table").bootstrapTable('refresh'); // 成功后刷新表格数据，如果你不用table插件，可以刷新页面
                newsModal.hide();
            } else {
                showNotify(msg, 'danger');
            }
            self.attr("autocomplete", "on").prop("disabled", false);
        }).fail(function () {
            loader.destroy();
            showNotify('服务器发生错误，请稍后再试', 'danger');
            self.attr("autocomplete", "on").prop("disabled", false);
        });
    });
    
    /**
     * 搜索按钮
     */
    $(document).on('click', '#search-btn', function() {
        $('#table').bootstrapTable('refresh');
    })
    
    /**
	 * 分页相关的配置
	 **/
	const pagination = {
		// 分页方式：[client] 客户端分页，[server] 服务端分页
		sidePagination: "server",
		// 初始化加载第一页，默认第一页
		pageNumber: 1,
		// 每页的记录行数
		pageSize: 10,
		// 可供选择的每页的行数 - (亲测大于1000存在渲染问题)
		pageList: [5, 10, 25, 50, 100],
		// 在上百页的情况下体验较好 - 能够显示首尾页
		paginationLoop: true,
		// 展示首尾页的最小页数
		paginationPagesBySide: 2
	};
	
	/**
	 * 按钮相关配置
	 **/
	const button = {
		// 按钮的类
		buttonsClass: 'default',
		// 类名前缀
		buttonsPrefix: 'btn'
	}
	
	/**
	 * 图标相关配置
	 **/
	const icon = {
		// 图标前缀
		iconsPrefix: 'mdi',
		// 图标大小
		iconSize: 'mini',
		// 图标的设置
		icons: {
		    paginationSwitchDown: 'mdi-door-closed',
		    paginationSwitchUp: 'mdi-door-open',
		    refresh: 'mdi-refresh',
		    toggleOff: 'mdi-toggle-switch-off',
		    toggleOn: 'mdi-toggle-switch',
		    columns: 'mdi-table-column-remove',
		    detailOpen: 'mdi-plus',
		    detailClose: 'mdi-minus',
		    fullscreen: 'mdi-monitor-screenshot',
		    search: 'mdi-table-search',
		    clearSearch: 'mdi-trash-can-outline'
		}
	};
	
	/**
	 * 表格相关的配置
	 **/
	const table = {
		classes: 'table table-bordered table-hover table-striped',
		// 请求地址
		url: '/news/list',
		// 唯一ID字段
		uniqueId: 'id',
		// 每行的唯一标识字段
		idField: 'id',
		// 是否启用点击选中行
		clickToSelect: true,
		// 是否显示详细视图和列表视图的切换按钮(clickToSelect同时设置为true时点击会报错)
		// showToggle: true,
		// 请求得到的数据类型
		dataType: 'json',
		// 请求方法
		method: 'post',
		// 工具按钮容器
		toolbar: '#toolbar',
		// 是否分页
		pagination: true,
		// 是否显示所有的列
		showColumns: true,
		// 是否显示刷新按钮
		showRefresh: true,
		// 显示图标
		showButtonIcons: true,
		// 显示文本
		showButtonText: false,
		// 显示全屏
		showFullscreen: true,
		// 开关控制分页
		showPaginationSwitch: true,
		// 总数字段
		totalField: 'total',
		// 当字段为 undefined 显示
		undefinedText: '-',
		// 排序方式
		sortOrder: "asc",
		...icon,
		...pagination,
		...button
	};
	
	/**
	 * 用于演示的列信息
	 **/
	const columns = [{
		field: 'example',
		checkbox: true,
		// 列的宽度
		width: 5,
		// 宽度单位
		widthUnit: 'rem'
	}, {
		field: 'id',
		title: '编号',
		// 使用[align]，[halign]和[valign]选项来设置列和它们的标题的对齐方式。
		// h表示横向，v标识垂直
		align: 'center',
		// 是否作为排序列
		sortable: true,
		// 当列名称与实际名称不一致时可用
		sortName: 'sortId',
		switchable: false,
		// 列的宽度
		width: 8,
		// 宽度单位
		widthUnit: 'rem'
	}, {
		field: 'type',
		align: 'center',
		title: '栏目',
		titleTooltip: '栏目',
        formatter:function(value, row, index){ 
			var value = "";
			if (row.type == '1') {
				value = '小说';
			} else if(row.type == '2') {
				value = '古籍';
			} else if(row.type == '3') {
				value = '专辑';
			} else {
				value = '自传';
			}
			return value;
		}
	}, {
		field: 'title',
		align: 'center',
		title: '标题',
	}, {
		field: 'author',
		align: 'center',
		title: '作者'
	}, {
        field: 'status',
        title: '状态',
        formatter:function(value, row, index){ 
			var value="";
			if (row.status == '0') {
				value = '<span class="badge bg-danger">禁用</span>';
			} else if(row.status == '1') {
				value = '<span class="badge bg-success">正常</span>';
			} else {
				value = '<span class="badge bg-secondary">未知</span>' ;
			}
			return value;
		}
    }, {
        field: 'operate',
        title: '操作',
        formatter: btnGroup,  // 自定义方法
        events: {
            'click .edit-btn': function (event, value, row, index) {
                event.stopPropagation();
                editUser(row);
            },
            'click .del-btn': function (event, value, row, index) {
                event.stopPropagation();
                delUser(row);
            }
        }
    }];
	
	$('#table').bootstrapTable({
		...table,
		// 自定义的查询参数
		queryParams: function (params) {
			return {
				// 每页数据量
				limit: params.limit,
				// sql语句起始索引
				offset: params.offset,
				page: (params.offset / params.limit) + 1,
				// 排序的列名
				sort: params.sort,
				// 排序方式 'asc' 'desc'
				sortOrder: params.order,
                // 搜索关键词
                title: $('#title').val()
			};
		},
		columns,
        onLoadSuccess: function(data){
            $("[data-bs-toggle='tooltip']").tooltip();
        }
	});
    
    // 自定义操作按钮
    function btnGroup () {
        let html =
            '<a href="#!" class="btn btn-sm btn-default me-1 edit-btn" title="编辑" data-bs-toggle="tooltip"><i class="mdi mdi-pencil"></i></a>' +
            '<a href="#!" class="btn btn-sm btn-default del-btn" title="删除" data-bs-toggle="tooltip"><i class="mdi mdi-window-close"></i></a>';
        return html;
    }
  
    // 操作方法 - 编辑
    function editUser(row) {
        $.ajax({
            type: "post",
            url: "/news/getInfo",
            data: { id: row.id },
            dataType: 'json',
            success: function (res, status) {
                if (res.code == '200') {
                    $('#newsModal').find('.modal-title span').text('编辑');
                    $('#newsModal').find('#news_id').val(res.data.id);
                    $('#newsModal').find('#type').val(res.data.type);
                    $('#newsModal').find('#title').val(res.data.title);
                    $('#newsModal').find('#author').val(res.data.author);
                    $('#newsModal').find('#content').val(res.data.content);
                    $('#newsModal').find('#sort').val(res.data.sort);
                    $('#newsModal').find('input[name="status"]').eq(res.data.status).attr('checked', true);
                    
                    if (!newsModal) {
                        newsModal = new bootstrap.Modal($('#newsModal').get(0), {
                            keyboard: false,
                            backdrop: 'static',
                        });
                    }
                    newsModal.show();
                } else {
                    showNotify(res.msg, 'danger');
                }
            },
            error: function () {
                showNotify('服务器发生错误，请稍后再试', 'danger');
            }
        });
    }
    // 操作方法 - 删除
    function delUser(row) {
        $.ajax({
            type: "post",
            url: "/news/delete",
            data: { id: row.id },
            dataType: 'json',
            success: function (res, status) {
                if (res.code == '200') {
                    showNotify(res.msg, 'info');
                    $("#table").bootstrapTable('refresh');
                } else {
                    showNotify(res.msg, 'danger');
                }
            },
            error: function () {
                showNotify('服务器发生错误，请稍后再试', 'danger');
            }
        });
    }
</script>
</body>
</html>
